#ifndef _lsusb_
#define _lsusb_

#include "../include/defs.h"

#define CLR_RH_PORTSTAT(x) \
    status = inw(io_addr+USBPORTSC1); \
    status = (status & 0xfff5) & ~(x); \
    outw(status, io_addr+USBPORTSC1)

#define SET_RH_PORTSTAT(x) \
    status = inw(io_addr+USBPORTSC1); \
    status = (status & 0xfff5) | (x); \
    outw(status, io_addr+USBPORTSC1)

/* Command register */
#define USBCMD                  0
#define USBCMD_RS               0x0001  /* Run/Stop */
#define USBCMD_HCRESET          0x0002  /* Host reset */
#define USBCMD_GRESET           0x0004  /* Global reset */
#define USBCMD_EGSM             0x0008  /* Global Suspend Mode */
#define USBCMD_FGR              0x0010  /* Force Global Resume */
#define USBCMD_SWDBG            0x0020  /* SW Debug mode */
#define USBCMD_CF               0x0040  /* Config Flag (sw only) */
#define USBCMD_MAXP             0x0080  /* Max Packet (0 = 32, 1 = 64) */

/* Status register */
#define USBSTS                  2
#define USBSTS_USBINT           0x0001  /* Interrupt due to IOC */
#define USBSTS_ERROR            0x0002  /* Interrupt due to error */
#define USBSTS_RD               0x0004  /* Resume Detect */
#define USBSTS_HSE              0x0008  /* Host System Error - basically PCI problems */
#define USBSTS_HCPE             0x0010  /* Host Controller Process Error - the scripts were buggy */
#define USBSTS_HCH              0x0020  /* HC Halted */

/* Interrupt enable register */
#define USBINTR                 4
#define USBINTR_TIMEOUT         0x0001  /* Timeout/CRC error enable */
#define USBINTR_RESUME          0x0002  /* Resume interrupt enable */
#define USBINTR_IOC             0x0004  /* Interrupt On Complete enable */
#define USBINTR_SP              0x0008  /* Short packet interrupt enable */

#define USBFRNUM                6
#define USBFLBASEADD            8
#define USBSOF                  12

/* USB port status and control registers */
#define USBPORTSC1              16
#define USBPORTSC2              18
#define USBPORTSC_CCS           0x0001  /* Current Connect Status ("device present") */
#define USBPORTSC_CSC           0x0002  /* Connect Status Change */
#define USBPORTSC_PE            0x0004  /* Port Enable */
#define USBPORTSC_PEC           0x0008  /* Port Enable Change */
#define USBPORTSC_LS            0x0030  /* Line Status */
#define USBPORTSC_RD            0x0040  /* Resume Detect */
#define USBPORTSC_LSDA          0x0100  /* Low Speed Device Attached */
#define USBPORTSC_PR            0x0200  /* Port Reset */
#define USBPORTSC_SUSP          0x1000  /* Suspend */

typedef struct
{
    unsigned short VendorID;
    unsigned short DeviceID;
    short CommandReg;
    short StatusReg;
    short RevisionID;
    char SubClass;
    char ClassCode;
    char CachelineSize;
    char Latency;
    char HeaderType;
    char BIST;
    int BAR0;
    int BAR1;
    int BAR2;
    int BAR3;
    int BAR4;
    int BAR5;
    int CardbusCISPtr;
    short SubVendorID;
    short SubDeviceID;
    int ExRomAddress;
    int Reserved1;
    int Reserved2;
    char IRQ;
    char PIN;
    char MinGrant;
    char MaxLatency;
}PCI_Device_t;

#define FLLen 10

typedef struct
{
  int irq;
  unsigned int io_addr;
  unsigned int io_size;
  unsigned int maxports;
  int running;

  int apm_state;

//   int unlink_urb_done;
//   atomic_t avoid_bulk;
// 
//   struct usb_bus *bus;	// our bus
// 
int frameList[FLLen];
//   uhci_desc_t **iso_td;
//   uhci_desc_t *int_chain[8];
//   uhci_desc_t *ls_control_chain;
//   uhci_desc_t *control_chain;
//   uhci_desc_t *bulk_chain;
//   uhci_desc_t *chain_end;
//   uhci_desc_t *td1ms;
//   uhci_desc_t *td32ms;
//   struct list_head free_desc;
//   spinlock_t qh_lock;
//   spinlock_t td_lock;
//   struct virt_root_hub rh;  //private data of the virtual root hub
//   int loop_usage;    // URBs using bandwidth reclamation
// 
//   long timeout_check;
//   int timeout_urbs;
//   struct pci_dev *uhci_pci;
} uhci_t;


/*Lista todos los dispositivos usb*/
int lsusb(int argc, char **argv);
int lspci(int argc, char **argv);

#endif
